#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <cerrno>
#include "../../mqcommon/mq_log.hpp"

class FileHelper
{
public:
    FileHelper(const std::string &filename)
        : _filename(filename)
    {
        EnableScreen();
    }

    bool exists()
    {
        struct stat st;
        return (::stat(_filename.c_str(), &st) == 0); // 不考虑权限不足的问题
    }

    size_t size()
    {
        struct stat st;
        int ret = ::stat(_filename.c_str(), &st);
        if (ret < 0)
        {
            LOG(FATAL, "文件不存在!!!");
        }
        return st.st_size;
    }

    bool read(char *body, size_t offset, size_t len)
    {
        // 打开文件
        std::ifstream ifs(_filename, std::ios::binary | std::ios::in); // 文本读取会导致格式“美化”
        if (ifs.is_open() == false)
        {
            LOG(FATAL, "文件未打开!!!");
            return false;
        }
        // 跳转到指定位置
        ifs.seekg(offset);
        // 读取
        ifs.read(body, len);
        if (ifs.good() == false)
        {
            LOG(FATAL, "%s 文件读取失败!!!", _filename);
            return false;
        }
        // 关闭
        ifs.close();
        return true;
    }

    // 复用
    bool read(std::string &body)
    {
        size_t size = this->size();
        body.resize(size);
        return read(&body[0], 0, size);
    }

    bool write(const char *body, size_t offset, size_t len)
    {
        // 打开文件
        std::fstream fs(_filename, std::ios::binary | std::ios::out | std::ios::in);
        if (fs.is_open() == false)
        {
            LOG(FATAL, "文件打开失败!!!");
            return false;
        }
        // 跳转到指定位置
        fs.seekp(offset);
        // 写
        fs.write(body, len);
        if (fs.good() == false)
        {
            LOG(FATAL, "%s 文件写入失败!!!", _filename);
            return false;
        }
        // 关闭
        fs.close();
        return true;
    }
    bool write(const std::string &body)
    {
        return write(body.c_str(), 0, body.size());
    }

    bool rename(const std::string &target_name)
    {
        return (::rename(_filename.c_str(), target_name.c_str()) == 0);
    }

    static std::string parentDir(const std::string &filepath)
    {
        size_t pos = filepath.find_last_of("/");
        if (pos == std::string::npos)
        {
            return "./";
        }
        std::string path = filepath.substr(0, pos);
        return path;
    }

    static bool createFile(const std::string &filename)
    {
        std::fstream fs(filename, std::ios::out | std::ios::binary); // binary方便跨平台
        if (fs.is_open() == false)
        {
            LOG(FATAL, "文件创建失败!!!");
            return false;
        }
        fs.close();
        return true;
    }

    static bool removeFile(const std::string &filename)
    {
        return ::remove(filename.c_str()) == 0;
    }

    static bool createDirectory(const std::string &filepath)
    {
        size_t pos = 0, idx = 0;
        while (idx < filepath.size())
        {
            pos = filepath.find("/", idx);
            if (pos == std::string::npos)
                return mkdir(filepath.c_str(), 0775);

            std::string path = filepath.substr(0, pos);
            int ret = mkdir(path.c_str(), 0775);
            if (ret != 0 && errno != EEXIST)
            {
                LOG(ERROR, "创建目录%s失败:%s", path.c_str(), strerror(errno));
                return false;
            }
            idx = pos + 1;
        }
        return false;
    }

    static bool removeDirectory(const std::string &path)
    {
        std::string cmd = "rm -rf " + path;
        return system(cmd.c_str()) != -1;
    }

private:
    std::string _filename;
};

int main()
{
    // // 文件是否存在
    // FileHelper fh("test.txt");
    // LOG(DEBUG, "文件是否存在：%d\n", fh.exists());
    // // 创建文件
    // LOG(DEBUG, "文件创建是否成功：%d", fh.createFile("test.txt"));
    // // 是否存在
    // // FileHelper fh_test("test.txt");
    // // LOG(DEBUG, "文件是否存在：%d\n", fh_test.exists());

    // // 写文件
    // std::string body = "1234567890";
    // bool ret = fh.write(body);
    // LOG(DEBUG, "文件是否写入成功：%d\n", ret);
    

    // // // 读取文件
    // // ret = fh.read(body);
    // // LOG(DEBUG, "文件是否读取成功：%d\n", ret);
    // // std::cout << body << std::endl;
    // // char buf[10];
    // // ret = fh.read(buf,2,5);
    // // std::cout << buf << std::endl;

    // // body = "123456";
    // // fh.createFile("test.txt");
    // // fh.write(body.c_str(), 1,2);
    // // fh.read(body);
    // // std::cout << body << std::endl;

    // // 文件大小
    // size_t size = fh.size();
    // LOG(DEBUG, "文件的大小为：%d\n", size);
    // // 删除文件
    // FileHelper::removeFile("test.txt");
    // FileHelper::removeFile("../../1.txt");
    // // 创建目录
    // // FileHelper::createDirectory("aaa/bbb/ccc/");
    // // 删除目录
    // FileHelper::removeDirectory("aaa");

    FileHelper::createDirectory("./aaa/bbb/ccc");
    FileHelper::createFile("./aaa/bbb/test.txt");
    return 0;
}